// mapMethods.ts
import Map from 'ol/Map';
import View from 'ol/View';
import { defaults as Defaults } from 'ol/control.js';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { Style, Icon, Stroke, Fill } from 'ol/style';
import Overlay from 'ol/Overlay';
import CircleStyle from 'ol/style/Circle';

// 存储地图实例
let mapInstance: Map | null = null;
let vectorSource: VectorSource;


/**
 * 初始化地图
 * target 地图渲染的dom
 */
export const initMap = (target: string): Map => {
  // 创建矢量图层源
  vectorSource = new VectorSource();

  // 天地图图层
  const source = new XYZ({
    url: 'http://t4.tianditu.com/DataServer?T=vec_w&tk=761d35504d4852532b586f4b529a6889&x={x}&y={y}&l={z}'
  });
  const tileLayer = new TileLayer({
    source: source,
    className: 'dark-layer'
  });

  // 标注图层
  const sourceMark = new XYZ({
    url: 'http://t4.tianditu.com/DataServer?T=cva_w&tk=761d35504d4852532b586f4b529a6889&x={x}&y={y}&l={z}'
  });
  const tileMark = new TileLayer({
    source: sourceMark,
    className: 'dark-layer'
  });

  // 创建矢量图层
  const vectorLayer = new VectorLayer({
    source: vectorSource
  });

  // 创建地图实例
  const map = new Map({
    target: target,
    layers: [tileLayer, tileMark, vectorLayer],
    view: new View({
      projection: 'EPSG:4326',
      center: [122.207216, 29.985295],
      zoom: 16,
      maxZoom: 20,
      minZoom: 1
    }),
    controls: Defaults({
      zoom: false,
      rotate: false
    })
  });

  // 设置地图实例
  mapInstance = map;
  
  return map;
};

/**
 * 获取地图实例
 */
const getMapInstance = (): Map => {
  if (!mapInstance) {
    throw new Error('地图尚未初始化');
  }
  return mapInstance;
};

/**
 * 获取矢量图层源
 * @returns 矢量图层源
 */
export const getVectorSource = (): VectorSource => {
  return vectorSource;
};

/**
 * 设置地图实例 - 用于外部设置地图
 * @param map 地图实例
 */
export const setMap = (map: Map): void => {
  mapInstance = map;
};

/**
 * 设置矢量数据源 - 用于外部设置矢量数据源
 * @param source 矢量数据源
 */
export const setVectorSource = (source: VectorSource): void => {
  vectorSource = source;
};

/**
 * 添加点位
 * coordinates[122.393281, 29.914175] iconPath点位图片 popupContent弹窗
 */
export const addPoint = (coordinates: [number, number], iconPath: string, popupContent: string): void => {
  const map = getMapInstance();
  
  const pointFeature = new Feature({
    geometry: new Point(coordinates)
  });

  pointFeature.setStyle(new Style({
    image: new Icon({
      src: iconPath,
      scale: 0.1
    })
  }));

  vectorSource.addFeature(pointFeature);

  // 创建弹窗
  const popupElement = document.createElement('div');
  popupElement.className = 'ol-popup';
  popupElement.innerHTML = `
    <div class="popup-content">
      ${popupContent}
      <button class="popup-close">关闭</button>
    </div>
  `;

  const overlay = new Overlay({
    element: popupElement,
    positioning: 'bottom-center',
    stopEvent: false,
    offset: [0, -50]
  });

  map.addOverlay(overlay);

  // 添加点击事件
  map.on('click', (event) => {
    map.forEachFeatureAtPixel(event.pixel, (feature) => {
      if (feature === pointFeature) {
        const geometry = feature.getGeometry();
        if (geometry instanceof Point) {
          overlay.setPosition(geometry.getCoordinates());
        }
      }
    });
  });

  // 添加关闭按钮事件
  popupElement.querySelector('.popup-close')?.addEventListener('click', () => {
    overlay.setPosition(undefined);
  });
};

/**
 * 设置地图视图中心点
 * @param coordinates 坐标 [经度, 纬度]
 * @param zoomLevel 缩放级别
 */
export const setViewToCoordinates = (
  coordinates: [number, number],
  zoomLevel: number = 16
): void => {
  const map = getMapInstance();
  map.getView().setCenter(coordinates);
  map.getView().setZoom(zoomLevel);
};

// 添加桥的特征
// 参数: bridgeName - 桥名, coordinates - 经纬度坐标, initialColor - 初始颜色
export const addBridge = (bridgeName: string, coordinates: [number, number], initialColor: string) => {
  const mapInstance = getMapInstance();
  const vectorSource = mapInstance.getLayers().getArray().find(layer => layer instanceof VectorSource) as VectorSource;

  const bridgeFeature = new Feature({
    geometry: new Point(coordinates),
    name: bridgeName
  });
  bridgeFeature.setStyle(new Style({
    image: new CircleStyle({
      radius: 10,
      fill: new Fill({ color: initialColor }),
      stroke: new Stroke({ color: 'black', width: 2 })
    })
  }));
  vectorSource.addFeature(bridgeFeature);
};

// 根据桥名定位视角并改变颜色
// 参数: bridgeName - 桥名
export const focusOnBridge = (bridgeName: string) => {
  const mapInstance = getMapInstance();
  const vectorSource = mapInstance.getLayers().getArray().find(layer => layer instanceof VectorSource) as VectorSource;

  vectorSource.getFeatures().forEach((feature) => {
    if (feature.get('name') === bridgeName) {
      const geometry = feature.getGeometry();
      if (geometry instanceof Point) {
        const coordinates = geometry.getCoordinates();
        setViewToCoordinates([coordinates[0], coordinates[1]]);
        changeBridgeColor(feature, 'red'); // 假设点击后颜色变为红色
      }
    }
  });
};

// 改变桥的颜色
// 参数: bridgeFeature - 桥要素, color - 颜色
export const changeBridgeColor = (bridgeFeature: Feature, color: string) => {
  bridgeFeature.setStyle(new Style({
    image: new CircleStyle({
      radius: 10,
      fill: new Fill({ color: color }),
      stroke: new Stroke({ color: 'black', width: 2 })
    })
  }));
};

/**
 * 清除所有点位
 */
export const clearAllFeatures = (): void => {
  vectorSource.clear();
};
// 其他地图方法可以在这里定义